<template>
  <el-dialog
    v-model="state.dialogVisible"
    :append-to-body="false"
    :before-close="close"
    :close-on-click-modal="true"
    :close-on-press-escape="true"
    :destroy-on-close="true"
    top="5vh"
    :modal="model"
    :title="state.dialogTitle"
    :width="width"
  >
    <el-row :gutter="10">
      <el-col :span="5">
        <div class="card-container">
          <el-card :body-style="{ padding: '5px' }" shadow="never">
            <template #header>
              <span class="card-title">角色分类</span>
            </template>
            <div class="card-content">
              <el-tree
                ref="roleTreeRef"
                accordion
                :check-strictly="true"
                class="custom-tree"
                :data="treeOptions.dataList"
                highlight-current
                node-key="id"
                :props="treeOptions.props"
                :show-checkbox="false"
                @node-click="handleNodeClick"
              />
            </div>
          </el-card>
        </div>
      </el-col>
      <el-col :span="19">
        <el-row :gutter="0">
          <el-col :span="24">
            <el-form :inline="true" label-width="80px" :model="tableOptions.queryForm">
              <el-form-item label="角色编码">
                <el-input v-model="tableOptions.queryForm.roleCode" placeholder="角色编码" />
              </el-form-item>
              <el-form-item label="角色名称">
                <el-input v-model="tableOptions.queryForm.roleName" placeholder="角色名称" />
              </el-form-item>
              <el-form-item>
                <el-button type="warning" icon="refresh-left" @click="handleResetQuery">
                  重置
                </el-button>
                <el-button type="primary" icon="Search" @click="queryTableData"> 查询 </el-button>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
        <el-table
          ref="roleTableRef"
          v-loading="tableOptions.loading"
          border
          stripe
          :data="tableOptions.dataList"
          :height="tableOptions.height"
          :cell-style="tableStyle.cellStyle"
          :header-cell-style="tableStyle.headerCellStyle"
          @sort-change="handleSortChange"
          @selection-change="handleSelectionChange"
          @row-click="handleRowClick"
        >
          <el-table-column align="center" show-overflow-tooltip type="selection" width="60" />
          <el-table-column label="序号" type="index" width="60">
            <template #default="{ $index }">
              {{ $index + 1 }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="角色编码" prop="roleCode" width="120" />
          <el-table-column align="center" label="角色名称" prop="roleName" width="120" />
          <el-table-column align="center" label="排序号" prop="orderId" width="70" />
          <el-table-column align="center" label="角色类别" prop="roleTypeName" width="140" />
          <el-table-column
            align="center"
            label="备注"
            prop="remark"
            show-overflow-tooltip
            width="140"
          />
          <el-table-column
            align="center"
            :formatter="datetimeFormat"
            label="创建时间"
            prop="createTime"
            width="160"
          />
        </el-table>
        <el-pagination
          background
          :current-page="tableOptions.pagination.current"
          :layout="tableOptions.pagination.layout"
          :page-size="tableOptions.pagination.size"
          :total="tableOptions.pagination.total"
          @current-change="handleCurrentChange"
          @size-change="handleSizeChange"
        />
        <div class="selections-items" v-if="state.selectedList.length > 0">
          <el-tag
            v-for="(tag, index) in state.selectedList"
            :key="tag.id"
            type="primary"
            closable
            style="margin-right: 10px"
            @close="handleReduce(index, tag.id)"
          >
            {{ tag.text }}
          </el-tag>
        </div>
      </el-col>
    </el-row>
    <template #footer>
      <el-button icon="circle-close" type="warning" @click="close"> 取消 </el-button>
      <el-button icon="circle-check" type="primary" @click="save"> 确定 </el-button>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { queryRoleTable } from "@/api/admin/org/role";
import { querySystemTreeNode } from "@/api/admin/system/systemtree";
import { datetimeFormat } from "@/utils/common";
import { useTable, type BasicTableProps } from "@/hooks/table";
import { useTree, type BasicTree } from "@/hooks/tree";
import { onMounted, reactive, ref, watch } from "vue";

const props = defineProps({
  title: {
    type: String,
    default: "选择角色"
  },
  width: {
    type: String,
    default: "70%"
  },
  model: {
    type: Boolean,
    default: true
  },
  multiple: {
    type: Boolean,
    default: true
  }
});

const emits = defineEmits(["change"]);

const roleTreeRef = ref(null);
const roleTableRef = ref(null);

const state = reactive({
  dialogTitle: props.title,
  dialogVisible: false,
  selectedList: []
});

const tableOptions = reactive<BasicTableProps>({
  queryForm: {
    roleTypeCode: "ALL",
    roleCode: "",
    roleName: ""
  },
  queryFunction: queryRoleTable,
  descs: ["create_time"]
});

const {
  tableStyle,
  queryTableData,
  handleSelectionChange,
  handleResetQuery,
  handleRowClick,
  handleSizeChange,
  handleCurrentChange,
  handleSortChange,
  handleToggleHeight
} = useTable(tableOptions, roleTableRef);

const treeOptions = reactive<BasicTree>({
  queryForm: { treeCode: "role" },
  props: {
    children: "children",
    label: "text",
    isLeaf: "leaf"
  },
  queryFunction: querySystemTreeNode
});

const { queryTreeData } = useTree(treeOptions);

onMounted(() => {
  queryTreeData();
  queryTableData();
  handleToggleHeight(150);
});

watch(
  () => tableOptions.dataSelections,
  val => {
    //过滤出不在state.selectedList中的行并加入到state.selectedList中。
    if (props.multiple) {
      val.forEach(n => {
        if (!state.selectedList.some(m => m.id === n.id)) {
          state.selectedList.push({ id: n.id, text: n.roleName });
        }
      });
    } else {
      state.selectedList = [];
      const n = tableOptions.dataSelections[0];
      state.selectedList.push({ id: n.id, text: n.roleName });
    }
  }
);

const show = () => {
  state.selectedList = [];
  state.dialogVisible = true;
};

const close = () => {
  state.selectedList = [];
  state.dialogVisible = false;
};

const save = () => {
  emits("change", state.selectedList);
  close();
};

const handleNodeClick = data => {
  if (data.nodeCode) {
    queryTableData({ roleTypeCode: data.nodeCode }, false, false);
  }
};

const handleReduce = (index, id) => {
  const list = tableOptions.dataList.filter(n => n.id === id);
  if (list && list.length > 0) {
    roleTableRef.value.toggleRowSelection(list[0], false);
  }
  state.selectedList.splice(index, 1);
};

defineExpose({
  save,
  show,
  close
});
</script>
<style lang="scss" scoped>
.selections-items {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  margin-left: 10px;
}

.card-content {
  height: 380px;
  min-height: 380px;
  overflow: auto;
}
</style>
